package com.zeus.controller;

import com.github.pagehelper.PageInfo;
import com.zeus.pojo.*;
import com.zeus.service.*;
import com.zeus.JsonWebToken.JWTUtil;
import com.zeus.util.JsonObject;
import com.zeus.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author 冯扬龙
 * @date 2021/6/10 12:32
 */
@Controller
@RequestMapping("/post")
public class PostController {

    @Autowired
    private PostService postService;

    @Autowired
    private TypeService typeService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private NoticeService noticeService;

    @Autowired
    private UserService userService;

    /**
     * 后台：
     查询功能,高级查询+数据渲染在后端页面上，高级查询走的是mapper层的这个方法，渲染数据走的是service层的方法
     */
    @RequestMapping("/queryPointAndAllPost")
    @ResponseBody
    public JsonObject queryPointAndAllPost(@RequestParam(defaultValue = "1") int page,
                                 @RequestParam(defaultValue = "15") int pageSize,
                                 Post post) {
        PageInfo<Post> pageInfo = postService.queryPointAndAllPost(page, pageSize, post);
//        创建跟前端交互的接口,创建返回的对象
        JsonObject object = new JsonObject(0, "ok", pageInfo.getTotal(), pageInfo.getList());
        return object;
    }


    /**
     * 后台：
     删除功能，支持批量删除，前端传过来的是id字符串集合，假如是只删除一个的话就是一个字符串，假如同时选中多个的话就是批量删除
     所以支持单一删除和批量删除
     */
    @RequestMapping("/deletePostById")
    @ResponseBody
    public R deletePostById(String ids) {
//       把接收到的字符串转集合对象
        List<String> list = Arrays.asList(ids.split(","));
        for (String id : list) {
            postService.deletePostById(Integer.parseInt(id));
        }
        return R.ok();
    }


    /**
     * 前后台交互，首页数据渲染：
     * 进入首页查询出后台需要传到前端的数据再显示在首页上
     *1.根据标签来统计丢失物品的数量然后显示在页面上
     * 2.要查出每条发布的启事下的对应评论数+曝光次数
     * 3.查询公告信息
     * 4.查询别人发布的招领启事总共有多少条显示在页面上
     * 5.右上角可以通过标题查询，利用solr服务器做缓存
     * 查询的时候也会走后台之前的查询方法所以只需要在mapper.xml中添加对应的查询条件就可以不需要再重新写语句
     * 查询：title+status+flag+typename
     */
    @RequestMapping("/queryIndexList")
    @ResponseBody
    public Map showIndexList(@RequestBody Map<String, String> map) {

        Post post = new Post();
        /**
         * 前后台交互，首页数据渲染：
         对着右边栏的标签点击进入到相应的页面，右边栏有四个，正在寻找，已经找到，等待认领，已被认领，对着这四个标签
         点击，就会看到与标签相对应的post具体信息
         */
        if (map.containsKey("status")) {
            String status = map.get("status");
            post.setStatus(Integer.parseInt(status));
        }
        if (map.containsKey("flag")) {
            String flag = map.get("flag");
            post.setFlag(Integer.parseInt(flag));
        }
        if (map.containsKey("typeName")) {
            String typeName = map.get("typeName");
            post.setTypeName(typeName);
        }
        if(map.containsKey("title")){
            String title= map.get("title");
            post.setTitle(title);
        }

        /**
         这个map的作用就是把下面所有需要在首页显示的信息全部装在一起然后return给首页显示
         */
        Map m = new HashMap();
        PageInfo<Post> pageInfo = postService.queryPointAndAllPost(1, 100, post);
        List<Post> list = pageInfo.getList();
//        遍历list集合，放入每个发布的启事的评论信息，在pojo类post中加入新的属性comment=评论
        for (Post post1 : list) {
            /**
            通过post对象可以拿到postid，通过postid就可以查询自己发布启事的对应评论数
             */
            Integer id = post1.getId();
            int commentSum = commentService.getCommentsByPostId(id);
            /**
             拿到了id的数量以后造再放进post对象中显示在前端页面
             */
            post1.setCounts(commentSum);
        }
        m.put("list", list);

        /**
         * 前后台交互，首页数据渲染：
         根据右边栏的分类栏目，也就是分类信息（手机？电脑？笔记本？也就是type对象）来查询对应的post对象信息，
         对着标签点进去可以查看集具体的post信息
         所以才专门建了一个typevo类，因为前端页面只会显示标签的名字这也是为什么typevo类只有name的属性在里面id不算
         也就是说后台所有的type类型都会在前端这里展示出来
         */
        List<TypeVo> type = typeService.getCountsByType();
        m.put("typeList", type);
        /**
         * 前后台交互，首页数据渲染：
         * 右边栏有一个状态栏，我要实现的功能是根据对应的状态点击进去然后可以查看具体的post对象也就是具体的发布的信息
         * 显示在我的眼前，所以这个叫根据状态来查询对应的post对象
         失物招领已完成 1 0
         失物招领未完成 1 1
         寻物启事已完成 0 0
         寻物启事未完成 0 1
         status状态：1为进行中，0为结束',
         flag：1为失物招领，0为寻物启事',
         */
        int swzl = postService.getPostByFlagAndStatus(1, 0);
        int wswzl = postService.getPostByFlagAndStatus(1, 1);
        int xwqs = postService.getPostByFlagAndStatus(0, 0);
        int wxwqs = postService.getPostByFlagAndStatus(0, 1);
        m.put("swzl", swzl);
        m.put("wswzl", wswzl);
        m.put("xwqs", xwqs);
        m.put("wxwqs", wxwqs);
        /**
         * 前后台交互：
         查询最新公告信息，这个时候才用到了notice类，这是跟前台交互的方法，不需要集合只需要一条一条返回
         最后将从数据库中查到最新公告(管理员在后台编写发出的)直接一起渲染到前台的右下角公告栏
         */
        Notice notice = noticeService.queryNoticeByTime();
        m.put("notice",notice);
        return m;
    }

    /**
     * 前端首页：
     * 点击查看详情按钮：
     * 对着物品点击查看详情以后进入到详情页面,详情页面里需要查询关于本条启事的详细信息
     * 还有评论数+曝光次数，还可以查看评论的信息和恢复的信息，还可以对发布者进行打赏，页面右边放的是
     * 丢失的物品或者是需要找的东西的照片
     *这个方法最终返回的是post对象因为点击查看详情要显示的是这个启事的具体信息，也就是主体是这个启事
     * 1.根据id查询post的详细信息
     * 2.查询当前发布者的具体信息
     * 3.查询当前启示的评论信息
     * 4.对评论的评论进行回复以及提交
     */
    @RequestMapping("/queryDetailList")
    @ResponseBody
    public Post queryDetailList(@RequestBody Map<String, String> map) {
        /**
         * 前端首页：
         * 点击查看详情按钮：
         每个失物栏都会有查看详情这个按钮，点击这个按钮就可以自动拿到对应的postid,通过id就可以拿到对应的post对象
         */
        String postId = map.get("postId");
        Post post = postService.getPostByPostId(Integer.parseInt(postId));
//        获取评论信息数
        int commentCounts = commentService.getCommentsByPostId(Integer.parseInt(postId));
//        评论次数的增加
        post.setCounts(commentCounts);
//        点击查看详情应该相对应增加一次浏览记录viewCount
        int viewCount = post.getViewCount();
        Post p = new Post();
        p.setId(Integer.parseInt(postId));
        p.setViewCount(viewCount + 1);
        /**
         前端：
         首页渲染中有一个查看详情页面：
         点击查看详情页面：
         每个认只要点开了详情那么曝光次数就应该+1，所以这个方法是增加曝光次数的
         */
        postService.addViewCount(p);
        return post;
    }


    /**
     * 前端：
     * 点击发布模块：
     * 进入相应的发布页面，里面需要显示类型(寻物还是认领)，物品分类（下拉框，衣服还是书本）
     * 标题，详细文字描述，还有图片，然后最后一个就是发布按钮
     * 这个方法的作用就是点击发布按钮发布,发布的时候肯定要发布的是相关物品类型的信息也就是post对象
     * +要上传的图片也就是说点击发送这个按钮里面会带这这些东西到后台来
     */
    @RequestMapping(value = "/shutPost",method = RequestMethod.POST)
    @ResponseBody
    public R shutPost(@RequestPart("post") Post post, HttpServletRequest request,
                           @RequestParam("upload") MultipartFile upload) throws IOException {
        //设置路径,意思就是你发布的东西图片要上传的地方
        String path = "E://images/";

        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        String filename = upload.getOriginalFilename();
        filename = UUID.randomUUID().toString().replace("-", "") + "_" + filename;
        upload.transferTo(new File(path, filename));
        String token = request.getHeader("token");
        String userName = JWTUtil.getUserName(token);
        post.setUname(userName);
        post.setPicture("/images/" + filename);
        post.setCtime(new Date());
        post.setStatus(1);
        post.setViewCount(0);
        int num = postService.shutPost(post);
        if (num > 0) {
            return R.ok();
        }
        return R.fail("网络状况出问题啦，请稍后再发布");
    }

    /**
     前端：
     进入个人详情页面
     1.需要知道自己发布过的东西，也就是post对象的所有信息
     2.自己万一丢失的物品找到了可以自己去删除自己发布过的信息
     3.假如自己丢失的物品找到了可以自己进入自己的详情页面更改启事的状态
     4.可以编辑自己的资料还有显示出自己的一部分资料
     */
    @RequestMapping("/queryMyList")
    @ResponseBody
    public Map queryMyList(HttpServletRequest request) {
        Post post = new Post();
        Map m = new HashMap();
        String token = request.getHeader("token");
        String username = JWTUtil.getUserName(token);
        Integer uid = JWTUtil.getUserId(token);
        post.setUname(username);
        PageInfo<Post> pageInfo = postService.queryPointAndAllPost(1, 100, post);
        List<Post> list = pageInfo.getList();
//        遍历list集合
        for (Post post1 : list) {
            Integer id = post1.getId();
            int commentSum = commentService.getCommentsByPostId(id);
            post1.setCounts(commentSum);
        }
        m.put("list", list);
//       查询个人的详细信息
        User user = userService.decideById(uid);
        m.put("user",user);
        return m;
    }

    /**
     前端：
     进入我的模块：
     我的模块中包括个人发布的招领/寻物信息+对个人的介绍也就是用户的详细信息+
     支持用户对物品信息状态的变更，还可以删除自己发布的信息,还可以编辑个人信息(头像的上传，打赏码)
     这个方法是修改状态信息，用户可以把自己正在招领的改为招领结束或者把进行中改为结束把结合改为进行
     当你点击修改按钮的时候会传postid过来，根据postid就可以对相应的post物品的状态进行修改
     */
    @RequestMapping("/updateStatus")
    @ResponseBody
    public R updateStatus(Integer id ,Integer status){
        Post post = new Post();
        post.setStatus(status);
        post.setId(id);
        int i = postService.updateStatus(post);
        if( i > 0){
            return  R.ok();
        }else {
            return R.fail("修改状态失败");
        }
    }

    /**
     前端：
     进入我的模块，我的模块中包括个人发布的招领/寻物信息+对个人的介绍也就是用户的详细信息+
     支持用户对物品信息状态的变更，还可以删除自己发布的信息,还可以编辑个人信息(头像的上传，打赏码)
     这个方法的作用是用户可以删除自己发布过的寻物启事，可以根据postId来删除，点击删除按钮的时候postid就在里面
     */
    @RequestMapping("/deleteSelfPost")
    @ResponseBody
    public R deleteSelfPost(@RequestParam Map<String,String> maps){
        String postId = maps.get("id");
        int i = postService.deletePostById(Integer.parseInt(postId));
        if( i > 0){
            return  R.ok();
        }else {
            return R.fail("删除失败");
        }
    }


}
